/*
** $ 身份：嘞解析器.h $
** 炉啊 解析器
** 请参见 炉啊.h中的版权声明
*
** 本人所用声母表: a啊 b哔 c西 d迪 e鹅 f弗 g哥 
* h喝 i艾 j鸡 k颗 l嘞 m摸 n恩
* o欧 p匹 q气 r日 s丝 t嚏 
* u由 v微 w屋 x斯 y医 z只
*
* 一些英文单词缩写,我的翻译大多来自;有道词典,谷歌翻译,百度.
* 一些术语实在不好翻译,所以就原封不动.
* 
*/

#ifndef 嘞解析器_喝
#define 嘞解析器_喝

#include "嘞极限.h"
#include "嘞对象.h"
#include "嘞只入出.h"

/*
** 表达式和变量描述符 .
** 代码生成为变量与表达式可以延迟允许
** 优化;  "表达式描述" 结构描述了可能延迟的
** 变量/表达式 . 它具有其 "主要" 值的说明以及
** 也可以产生其值的条件跳转列表 (生成的
** 由短路运算符 "与"/"或" ) .
*/

/* 变量/表达式 的种类 */
typedef enum {
  微空的,  /* 当'表达式描述'描述列表中的最后一个表达式时，
             这种类型意味着一个空列表(因此,没有表达式) */
  微无,  /* 常量无 */
  微真,  /* 常量真 */
  微假,  /* 常量假 */
  微常量,  /* 常量 在'常量'内; 信息 = 常量索引 在'常量'内 */
  微常量浮点,  /* 浮点常量; 浮点值 = 号值 浮点值 */
  微常量整型,  /* 整数常量; 整数值 = 号值 整数值 */
  微常量串,  /* 串常量; 串值 = 嚏串 地址;
             (串是固定的词汇器) */
  微非重定位,  /* 表达式有自己的值在固定的寄存器内;
                 信息 = 结果寄存器 */
  微本地,  /* 本地变量; 变量.栈索引 = 栈索引 (本地寄存器);
              变量.矢量索引 = 相对的索引 在'活动变量.数组'内  */
  微上值,  /* 上值变量; 信息 = 上值索引 在'上值'内 */
  微编译时常量,  /* 编译时常量; 信息 = 绝对索引 在'活动变量.数组'内  */
  微已索引,  /* 已索引变量;
                已索引.表 = 表寄存器;
                已索引.索引 = 键的寄存索引 */
  微索引上,  /* 已索引上值;
                已索引.表 = 表上值;
                已索引.索引 = 键的常量索引 */
  微索引整数, /* 已索引变量与常量整数;
                已索引.表 = 表寄存器;
                已索引.索引 = 键的值 */
  微索引串, /* 已索引变量与字面串;
                已索引.表 = 表寄存器;
                已索引.索引 = 键的常量索引 */
  微跳,  /* 表达式是一个 测试/对比 ;
            信息 = 程序计数对应的跳指令 */
  微重定位,  /* 表达式能放结果在任意寄存器内;
              信息 = 指令程序计数 */
  微调用,  /* 表达式是一个函数调用; 信息 = 指令程序计数 */
  微可变参数  /* 可变参数表达式; 信息 = 指令程序计数 */
} 表达式种类;

#define 微颗是否变量(颗)	(微本地 <= (颗) && (颗) <= 微索引串)
#define 微颗已索引(颗)	(微已索引 <= (颗) && (颗) <= 微索引串)

typedef struct 表达式描述 {
  表达式种类 常量;
  union {
    炉啊_整数 整数值;    /* 为 微颗整型 */
    炉啊_号码 浮点值;  /* 为 微颗浮点 */
    嚏串 *串值;  /* 为 微颗串 */
    int 信息;  /* 为 一般用途 */
    struct {  /* 为 已索引变量 */
      short 索引;  /* 索引 (寄存 或 "长型" 常量) */
      炉_字节 表;  /* 表 (寄存器 或 上值) */
    } 已索引;
    struct {  /* 为 本地变量 */
      炉_字节 栈索引;  /* 栈内索引 */
      unsigned short 矢量索引;  /* 编译器索引 (在 '活动变量.数组' 内)  */
    } 变量;
  } 由;
  int 小真;  /* 补丁列表于 '退出时候真' */
  int 小假;  /* 补丁列表于 '退出时候假' */
} 表达式描述;

/* 变量 的种类 */
#define 微迪颗正则		0   /* 正则 */
#define 寄存迪颗常量	1   /* 常量 */
#define 寄存迪颗待关闭	2   /* 待关闭 */
#define 寄存迪颗编译时常量		3   /* 编译时 常量 */

/* 活动本地变量的描述 */
typedef union 变量描述 {
  struct {
    嚏值字段;  /* 常量值(若它是编译时常量) */
    炉_字节 种类;
    炉_字节 栈索引;  /* 栈内变量索引 */
    short 原型索引;  /* 原型 '本地变量' 数组内的变量的索引 */
    嚏串 *名字;  /* 变量的名字 */
  } 微迪;
  嚏值 常量;  /* 常量值 (若任何) */
} 变量描述;

/* 对挂起的 去到 语句和签条语句的描述 */
typedef struct 签条描述 {
  嚏串 *名字;  /* 标识符签条 */
  int 程序计数;  /* 代码内位置 */
  int 行;  /* 它出现的那一行 */
  炉_字节 活动变量号码;  /* 位置内活动变量的号码 */
  炉_字节 关闭;  /* 去到逃离上值 */
} 签条描述;

/* 签条或去到 的列表 */
typedef struct 签条列表 {
  签条描述 *数组;  /* 数组 */
  int 号;  /* 可用条目的号码 */
  int 大小;  /* 数组大小 */
} 签条列表;

/* 解析器使用的动态结构 */
typedef struct 动态数据 {
  struct {  /* 所有本地活动变量的列表 */
    变量描述 *数组;
    int 号;
    int 大小;
  } 活动变量;
  签条列表 去到;  /* 待定去到的列表 */
  签条列表 签条;   /* 活动签条的列表 */
} 动态数据;

/* 区块的控制 */
struct 区块控制;  /* 在 嘞解析器.c 内定义 */


/* 国需要去 生成代码 对于给定函数 */
typedef struct 函国 {
  原型 *弗;  /* 当前函数头部 */
  struct 函国 *前一个;  /* 封闭函数 */
  struct 词国 *小词国;  /* 词汇国 */
  struct 区块控制 *区块;  /* 当前区块的链 */
  int 程序计数;  /* 下一个编码位置 (相当于 '号代码') */
  int 最后目标;   /*   最后 '跳 签条' 的'签条'*/
  int 前一个行;  /* 最后行 它被保存在 "行信息" 中 */
  int 常量号;  /* 在 '常量' 内的元素号码 */
  int 匹号;  /* 在 '匹' 内的元素号码 */
  int 绝对行信息号;  /* 在 '绝对行信息' 内的元素号码  */
  int 第一本地;  /* 第一本地变量索引 (在 动态数据数组 内) */
  int 第一签条;  /* 第一签条索引 (在 '动数->签条->数组' 内) */
  short 调试变量号;  /* 在 '弗->本地变量' 内的元素号码  */
  炉_字节 活动变量号;  /* 本地活动变量号码 */
  炉_字节 上值号;  /* 上值号码 */
  炉_字节 自由寄存器;  /* 第一自由寄存器 */
  炉_字节 绝对行的指令;  /* 指令发出自最后绝对行信息  */
  炉_字节 需要关闭;  /* 当返回时函数需要去关闭上值  */
} 函国;

炉啊艾_函 int 炉啊医_栈内变量号 (函国 *弗丝);
炉啊艾_函 嘞闭包 *炉啊医_解析器 (炉啊_国 *嘞, 只入出 *只, 摸缓冲 *缓冲冲,
                                 动态数据 *动数, const char *名字, int 第一印刻);


#endif